package com.atguigu.tingshu.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.context.OrderHandlerInterceptorContext;
import com.atguigu.tingshu.order.context.OrderTradeStrategyContext;
import com.atguigu.tingshu.order.enumeration.OrderStatusEnum;
import com.atguigu.tingshu.order.enumeration.PayWayEnum;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.order.strategy.OrderTradeStrategy;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderDerateMapper orderDerateMapper;


    @Override
    public OrderInfoVo trade(TradeVo tradeVo) {

        OrderTradeStrategy orderTradeStrategy = OrderTradeStrategyContext.getOrderTradeStrategy(tradeVo.getItemType());
        OrderInfoVo orderInfoVo = orderTradeStrategy.trade(tradeVo);

        return orderInfoVo;
    }

    @Override
    public String submitOrder(OrderInfoVo orderInfoVo) {

        OrderInfoVo orderInfoVo1 = OrderHandlerInterceptorContext.entry(orderInfoVo);
        String tradeNo = orderInfoVo1.getTradeNo();
        return tradeNo;
    }

    @Override
    public void orderCancel(String orderNo) {
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OrderInfo::getOrderNo, orderNo);
        OrderInfo orderInfo = orderInfoMapper.selectOne(lambdaQueryWrapper);

        String orderStatus = orderInfo.getOrderStatus();
        //如果订单状态是未支付,那么将状态改为已取消
        if (SystemConstant.ORDER_STATUS_UNPAID.equals(orderStatus)) {
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_CANCEL);
            // 使用乐观锁进行修改，防止在判断完毕以后，在修改之前用户对订单支付成功了
            lambdaQueryWrapper.eq(OrderInfo::getOrderStatus, SystemConstant.ORDER_STATUS_UNPAID);
            orderInfoMapper.update(orderInfo, lambdaQueryWrapper);
        }
    }

    @Override
    public void orderPaySuccess(String tradeNo) {
        // 修改订单的状态为已支付
        OrderInfo orderInfo = this.getOrderInfoByOrderNo(tradeNo);
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);     // 把订单的状态改为已支付
        orderInfoMapper.updateById(orderInfo);
        log.info("将订单的状态改为已支付...orderNo: {}", tradeNo);

        // 向Kafka中发送保存交易信息的消息, 消息的内容: orderNo , userId , itemIdList , itemType
        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
        userPaidRecordVo.setOrderNo(tradeNo);
        userPaidRecordVo.setUserId(orderInfo.getUserId());
        userPaidRecordVo.setItemType(orderInfo.getItemType());
        List<Long> itemIdList = orderInfo.getOrderDetailList().stream().map(orderDetail -> orderDetail.getItemId()).collect(Collectors.toList());
        userPaidRecordVo.setItemIdList(itemIdList);
        kafkaService.sendMessage(KafkaConstant.QUEUE_USER_PAY_RECORD, JSON.toJSONString(userPaidRecordVo));
        log.info("发送保存交易信息消息成功...infoContent: {}", JSON.toJSONString(userPaidRecordVo));
    }

    public OrderInfo getOrderInfoByOrderNo(String tradeNo) {

        // 创建LambdaQueryWrapper对象，封装查询条件
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OrderInfo::getOrderNo, tradeNo);
        OrderInfo orderInfo = orderInfoMapper.selectOne(lambdaQueryWrapper);

        // 查询订单所对应的明细数据
        LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderInfo.getId());
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(orderDetailLambdaQueryWrapper);
        orderInfo.setOrderDetailList(orderDetailList);

        // 查询订单的减免明细数据
        LambdaQueryWrapper<OrderDerate> derateLambdaQueryWrapper = new LambdaQueryWrapper<>();
        derateLambdaQueryWrapper.eq(OrderDerate::getOrderId, orderInfo.getId());
        List<OrderDerate> orderDerateList = orderDerateMapper.selectList(derateLambdaQueryWrapper);
        orderInfo.setOrderDerateList(orderDerateList);

        // 设置状态的名称
        orderInfo.setOrderStatusName(OrderStatusEnum.getOrderStatusName(orderInfo.getOrderStatus()));

        // 设置支付方式的名称
        orderInfo.setPayWayName(PayWayEnum.getPayWayName(orderInfo.getPayWay()));

        // 返回
        return orderInfo;
    }


    //    获取用户订单
    @Override
    public IPage<OrderInfo> findOrderInfoByPage(Integer pageNo, Integer pageSize) {
        // 获取当前登录用户的id
        Long userId = AuthContextHolder.getUserId();
        LambdaQueryWrapper<OrderInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(OrderInfo::getUserId, userId);

        // 创建Page对象
        Page<OrderInfo> page = new Page<>(pageNo, pageSize);
        this.page(page, lambdaQueryWrapper);

        page.getRecords().stream().forEach(orderInfo -> {

            Long orderId = orderInfo.getId();
            LambdaQueryWrapper<OrderDetail> detailLambdaQueryWrapper = new LambdaQueryWrapper<>();
            detailLambdaQueryWrapper.eq(OrderDetail::getOrderId, orderId);
            List<OrderDetail> orderDetailList = orderDetailMapper.selectList(detailLambdaQueryWrapper);
            orderInfo.setOrderDetailList(orderDetailList);

            orderInfo.setOrderStatusName(OrderStatusEnum.getOrderStatusName(orderInfo.getOrderStatus()));
            orderInfo.setPayWayName(PayWayEnum.getPayWayName(orderInfo.getPayWay()));

        });

        // 返回
        return page;
    }
}
